From b87d9e8dae8552e8fd7cbbd41e1d34fd0c925bff Mon Sep 17 00:00:00 2001 From: Debian Science Maintainers Date: Fri, 3 Jul 2026 22:13:01 +0100 Subject: [PATCH] Be reproducible, and don't fail on examples exceptions Don't execute example notebooks because some of them have unreproducible output, either numerical differences (small enough that I guess them to be machine-dependent rounding error not deliberate randomness) or extra cells (a single newline being split into its own cell vs part of the previous one). Copy them instead. At one point these 10 were affected, but skipping just them doesn't work because it seems 'random' which ones have the extra cells. count_hurdle discrete_choice_example discrete_choice_overview exponential_smoothing (and its images 14_0 and 16_0) generic_mle glm_formula glm_weights postestimation_poisson stats_poisson treatment_effect Also remove timestamps, ipykernel IDs, etc from examples output for reproducibility. (This is here not in debian/rules to do it before building the search index.) Skip some vector_ar cells that would print output (that would end up in the search index, so stripping it afterwards isn't enough). Author: Rebecca N. Palmer Forwarded: not-needed Gbp-Pq: Name sphinx_reproducibility_and_ignore_errors.patch --- docs/Makefile | 17 +++++++++++++++++ docs/source/conf.py | 1 + docs/source/vector_ar.rst | 8 ++++++++ examples/notebooks/stl_decomposition.ipynb | 4 ++-- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index a77686d..edea6c1 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -16,6 +16,8 @@ NOTEBOOKBUILD = nbgenerate.py # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter +SOURCE_DATE:=$(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+%a, %d %b %Y" || echo "xxx, xx xxx xxxx") +SOURCE_TIME:=$(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+%T" || echo "xx:xx:xx") # Put it first so that "make" without argument is like "make help". help: @@ -33,7 +35,22 @@ html: @echo "Executing notebooks from examples/notebooks folder" mkdir -p $(BUILDDIR)/source/examples/notebooks/generated # Black list notebooks from doc build here +ifeq ($(SOURCE_DATE_EPOCH),) $(TOOLSPATH)$(NOTEBOOKBUILD) --parallel --report-errors --skip-existing --execute-only --execution-blacklist statespace_custom_models +endif + @echo "Copying notebooks that were not executed (for reproducibility) or failed execution (there are usually several in Debian because some need network and/or dependencies we don't have)" + cp -nav ../examples/notebooks/*.ipynb -t source/examples/notebooks/generated || true +ifneq ($(SOURCE_DATE_EPOCH),) + @echo "Replacing timestamps and build paths in examples output for reproducibility" + for html in `find source/examples/notebooks/generated -name "*.html" -o -name "*.ipynb" -o -name "*.ipynb.txt"` ; do \ + sed -i -e 's#$(PYTHONPATH)/statsmodels/#/usr/lib/python3/dist-packages/statsmodels/#g' \ + -e 's# at 0x[0-9a-f]\{8,16\}\(>\|>\)# at 0xadde5de1e8ed\1#g' \ + -e 's#tmp/ipykernel_[0-9]\+#tmp/ipykernel_nnnnnnn#g' \ + -e 's#^\s\+.\(iopub.execute_input\|iopub.status.busy\|iopub.status.idle\|shell.execute_reply\).:.*# #g' \ + -e 's#\(Date:.*\)[A-Z][a-z]\+, \+[0-9]\+,\? \+[A-Z][a-z]\+,\? \+[0-9]\+#\1$(SOURCE_DATE)#g' \ + -e 's#\(Time:.*\)[0-9][0-9]:[0-9][0-9]:[0-9][0-9]#\1$(SOURCE_TIME)#g' $${html} ; \ + done +endif @echo "Running sphinx-build" @echo @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(O) @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(O) diff --git a/docs/source/conf.py b/docs/source/conf.py index 53ab2b4..f3b25f6 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -67,6 +67,7 @@ else: # nbsphinx options nbsphinx_allow_errors = True +ipython_warning_is_error = False # sphinxcontrib-spelling options spelling_word_list_filename = ['spelling_wordlist.txt', 'names_wordlist.txt'] spelling_ignore_pypi_package_names = True diff --git a/docs/source/vector_ar.rst b/docs/source/vector_ar.rst index 6168d95..7fe2774 100644 --- a/docs/source/vector_ar.rst +++ b/docs/source/vector_ar.rst @@ -127,6 +127,12 @@ likelihood test or information criteria-based order selection. We have implemented the latter, accessible through the :class:`VAR` class: .. ipython:: python + :suppress: + + model.select_order(15) + +.. ipython:: python + :verbatim: model.select_order(15) @@ -312,6 +318,7 @@ causality, but leave it to the reader. The :class:`VARResults` object has the F-test. .. ipython:: python + :verbatim: results.test_causality('realgdp', ['realinv', 'realcons'], kind='f') @@ -326,6 +333,7 @@ are Gaussian white noise. To test whether this assumption is consistent with a data set, :class:`VARResults` offers the `test_normality` method. .. ipython:: python + :verbatim: results.test_normality() diff --git a/examples/notebooks/stl_decomposition.ipynb b/examples/notebooks/stl_decomposition.ipynb index d2a429b..e8d6eee 100644 --- a/examples/notebooks/stl_decomposition.ipynb +++ b/examples/notebooks/stl_decomposition.ipynb @@ -570,7 +570,7 @@ "outputs": [], "source": [ "mod = STL(y, period=period, seasonal=seasonal)\n", - "%timeit mod.fit()\n", + "# removed for reproducibility: %timeit mod.fit()\n", "res = mod.fit()\n", "fig = res.plot(observed=False, resid=False)" ] @@ -598,7 +598,7 @@ " trend_jump=trend_jump,\n", " low_pass_jump=low_pass_jump,\n", ")\n", - "%timeit mod.fit()\n", + "# removed for reproducibility: %timeit mod.fit()\n", "res = mod.fit()\n", "fig = res.plot(observed=False, resid=False)" ] -- 2.30.2